package com.hqq.exercise.cal;

/**
 * Bign
 * 功能:设计一个高精度运算类
 * Created by heqianqian on 2017/8/8.
 */
public class Bign {

    private static final int MAX_LENGTH = 1000;

    /**
     * 逆序存储 防止计算时出现进位溢出
     */
    private int[] array;

    /**
     * 数值的位数
     * exp:number=1234 length = 4
     * array[0] = 4,array[1] = 3,arrat[2] = 2, array[3] = 1
     * array=[4,3,2,1,0....,0]
     * 便于除去先导0
     */
    private int length;

    public Bign() {
        array = new int[MAX_LENGTH];//数组初始化
    }

    public Bign(int num) {
        this();
        this.operator(num);
    }

    /**
     * 赋值
     */
    public void operator(int num) {
        int temp;
        while (num != 0) {
            temp = num % 10;
            array[length++] = temp;
            num = (num - num % 10) / 10;
        }
    }

    /**
     * 两个高精度的数相加
     */
    public Bign add(Bign bign) {
        Bign result = new Bign();
        int len = Math.min(bign.length, length);
        int carry = 0;//进位
        int temp = 0;//中间值
        for (int i = 0; i < len; i++) {
            temp = bign.array[i] + this.array[i] + carry;
            result.array[i] = temp % 10;
            result.length++;
            carry = temp / 10;
        }
        addRemain(result, bign.length > this.length ? bign : this, len, carry);
        return result;
    }

    /**
     * 两个高精度的数相减
     */
    public Bign subtract(Bign bign) {
        Bign result = new Bign();
        int len = Math.min(bign.length, length);
        int carry = 0;//借位
        int temp = 0;//中间值
        for (int i = 0; i < len; i++) {
            if (this.array[i] - bign.array[i] - carry < 0) {//产生借位
                temp = this.array[i] - bign.array[i] + 10 - carry;
                carry = 1;
            } else {
                temp =this.array[i] -  bign.array[i] - carry;
            }
            result.array[i] = temp;
            result.length++;
        }
        if (this.length>bign.length){
            for (int i = len; i < this.length; i++) {
                result.array[i] = this.array[i] - carry;
                result.length++;
            }
        }
        return result;
    }

    /**
     * 剩下未对齐的位数相加
     */
    private void addRemain(Bign result, Bign bign, int len, int carry) {
        for (int i = len; i < bign.length; i++) {
            result.array[i] = bign.array[i] + carry;
            result.length++;
        }
    }

    public void print() {
        for (int i = length - 1; i >= 0; i--) {
            System.out.print(array[i]);
        }
    }
}
